<?php

namespace app\console;

use app\common\service\AccountDetail;
use app\common\service\Consume;
use app\common\service\Customer;
use app\common\service\Mission;
use app\common\service\OnlinePay;
use app\common\service\Order;
use EasyWeChat\Factory;
use Predis\Client;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use app\enumerations\MissionTypeEnum;
use app\enumerations\MissionStatusEnum;
use app\enumerations\AccountDetailTypeEnum;

class TimeoutServer extends Command
{
    protected $server;

    // 命令行配置函数
    protected function configure()
    {
        // setName 设置命令行名称
        // setDescription 设置命令行描述
        $this->setName('setTimeout:start')->setDescription('Start SetTimeout Server!');
    }

    // 设置命令返回信息
    protected function execute(Input $input, Output $output)
    {
        $this->server = new \swoole_server('0.0.0.0', 9509);

        $this->server->set([
            'worker_num' => 4,
            'daemonize' => true,
            'log_file' => 'timeoutSwoole.txt'
        ]);

        $this->server->on('Start', [$this, 'onStart']);
        $this->server->on('Connect', [$this, 'onConnect']);
        $this->server->on('Receive', [$this, 'onReceive']);
        $this->server->on('Close', [$this, 'onClose']);

        $this->server->start();

    }

    // 主进程启动时回调函数
    public function onStart(\swoole_server $server)
    {
        echo "Start" . PHP_EOL;

        $missionService = new Mission();
        // 初始化未完成task任务
        $missionList = $missionService->getWaitingList(
            MissionTypeEnum::getEnumValue(MissionTypeEnum::SETTIMEOUT_CODE));

        foreach ($missionList as $mission) {
            $this->publishTask($server, $mission["mission_code"], $mission["execute_time"]);
        }

    }

    // 建立连接时回调函数
    public function onConnect(\swoole_server $server, $fd, $from_id)
    {
        echo "Connect" . PHP_EOL;
    }


    // 收到信息时回调函数
    public function onReceive(\swoole_server $server, $fd, $from_id, $data)
    {
        echo "message: {$data} form Client: {$fd}" . PHP_EOL;

        $taskData = json_decode($data, true);

        $returnData = $this->swooleReturn(200);

        if (!isset($taskData["mission_code"])
            || !isset($taskData["execute_time"])) {

            $returnData = $this->swooleReturn(-1, "传参格式错误");

        }

        //将受到的客户端消息再返回给客户端
        $server->send($fd, $returnData);

        // 执行任务
        $this->publishTask($server,
            $taskData["mission_code"], $taskData["execute_time"]);

    }

    public function onAfter($data)
    {

        $data = json_decode($data, true);

        $missionCode = $data["mission_code"];
        $executeTime = $data["execute_time"];

        // 当前时间
        $now = getCurrentTime();

        // 判断执行时间是否大于当前时间  如果大于当前时间继续发布延迟任务
        if ($executeTime > $now) {
            $this->publishTask($this->server, $missionCode, $executeTime);
            return false;
        }

        $missionService = new Mission();

        $mission = $missionService
            ->findByMissionCode($missionCode);

        if (isNullOrEmpty($mission)) {
            return false;
        }

        if ($mission["status"] !=
            MissionStatusEnum::getEnumValue(MissionStatusEnum::WAITING_CODE)) {
            return false;
        }

        $param = json_decode($mission["param"], true);

        $missionService = new Mission();

        // 更新任务已完成
        $missionData["status"] = MissionStatusEnum::getEnumValue(MissionStatusEnum::END_CODE);
        $missionData["end_time"] = getCurrentTime();

        $missionService->updateByIdAndData($mission["id"], $missionData);


        $taskType = $param["task_type"];

        switch ($taskType) {

            default:
                break;
        }


//        $this->server->send( $param['fd'] , $param['msg']);
    }

    // 关闭连时回调函数
    public function onClose(\swoole_server $server, $fd, $from_id)
    {
        echo "Close" . PHP_EOL;
    }

    //调用返回
    protected function swooleReturn($code, $msg = "", $data = "")
    {
        $returnData["code"] = $code;
        $returnData["msg"] = $msg;
        $returnData["data"] = $data;

        return json_encode($returnData);
    }

    protected function publishTask($server, $missionCode, $executeTime)
    {

        $secondsGap = (strtotime($executeTime) - time()) * 1000;

        if ($secondsGap < 0) {
            $secondsGap = 1000;
        } else {

            if ($secondsGap > 86400000) {
                $secondsGap = 86400000;
            }

        }

        $server->after($secondsGap, array($this, 'onAfter'),
            json_encode([
                "mission_code" => $missionCode,
                "execute_time" => $executeTime
            ]));

        var_dump("开启任务：".$missionCode."，执行时间为：".$executeTime);

    }

}